/* eslint-disable no-magic-numbers */
/* eslint-disable max-len */
export default class Calculate {
	constructor(num) {
		this.resultArr = [];
		this.resultArr.push(Calculate.valid(num));
	}
	static valid(num) {
		if (num < Number.MIN_SAFE_INTEGER || num > Number.MAX_SAFE_INTEGER || num && Math.abs(num) < Number.EPSILON) {
			throw new Error(`Number ${num} invalid`);
		}
		return num;
	}
	static decPartLen(num) {
		return (Calculate.valid(num).toString().split('.')[1] || '').length;
	}
	get result() {
		return this.resultArr.slice(-1)[0];
	}
	plus(currNum) {
		let prevNum = this.result;
		let i = Math.pow(10, Math.max(Calculate.decPartLen(prevNum), Calculate.decPartLen(currNum)));
		this.resultArr.push(Calculate.valid(Calculate.valid(Calculate.valid(prevNum * i) + Calculate.valid(currNum * i)) / i));
		return this;
	}
	minus(currNum) {
		let prevNum = this.result;
		let i = Math.pow(10, Math.max(Calculate.decPartLen(prevNum), Calculate.decPartLen(currNum)));
		this.resultArr.push(Calculate.valid(Calculate.valid(Calculate.valid(prevNum * i) - Calculate.valid(currNum * i)) / i));
		return this;
	}
	multiply(currNum) {
		let prevNum = this.result;
		let i1 = Math.pow(10, Calculate.decPartLen(prevNum)),
			i2 = Math.pow(10, Calculate.decPartLen(currNum));
		this.resultArr.push(Calculate.valid(Calculate.valid((prevNum * i1) * (currNum * i2)) / i1 / i2));
		return this;
	}
	divide(currNum) {
		let prevNum = this.result;
		let i1 = Math.pow(10, Calculate.decPartLen(prevNum)),
			i2 = Math.pow(10, Calculate.decPartLen(currNum));
		this.resultArr.push(Calculate.valid(Calculate.valid(Calculate.valid(Calculate.valid(prevNum * i1) / Calculate.valid(currNum * i2)) / i1) * i2));
		return this;
	}
	remainder(currNum) {
		this.divide(currNum);
		this.resultArr.splice(-1, 1, parseInt(this.result, 10));
		this.multiply(currNum);
		let subtrahend = this.result;
		this.resultArr.splice(-2, 2);
		this.minus(subtrahend);
		return this;
	}
	modulo(currNum) {
		this.divide(currNum);
		this.resultArr.splice(-1, 1, Calculate.valid(Math.floor(this.result)));
		this.multiply(currNum);
		let subtrahend = this.result;
		this.resultArr.splice(-2, 2);
		this.minus(subtrahend);
		return this;
	}
	valueOf() {
		return this.result;
	}
	toString() {
		return this.result.toString();
	}
}
